package cc.mrbird.febs.server.referral.service.impl;

import cc.mrbird.febs.common.core.entity.FebsResponse;
import cc.mrbird.febs.server.referral.dto.UserDTO;
import cc.mrbird.febs.server.referral.dto.WxUserDTO;
import cc.mrbird.febs.server.referral.entity.Doctor;
import cc.mrbird.febs.server.referral.entity.OAuthToken;
import cc.mrbird.febs.server.referral.entity.WxUser;
import cc.mrbird.febs.server.referral.mapper.DoctorMapper;
import cc.mrbird.febs.server.referral.mapper.WxUserMapper;
import cc.mrbird.febs.server.referral.service.IOAuthService;
import cc.mrbird.febs.server.referral.service.IWxUserService;
import cc.mrbird.febs.server.referral.utils.WXCore;
import cc.mrbird.febs.common.core.entity.ResponseCode;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cc.mrbird.febs.common.core.entity.QueryRequest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * 微信用户信息表 Service实现
 *
 * @author MrBird
 * @date 2021-02-24 10:39:20
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class WxUserServiceImpl extends ServiceImpl<WxUserMapper, WxUser> implements IWxUserService {

    @Value("${wx.appid}")
    private String  appid;
    @Value("${wx.user_register_password}")
    private String userRegisterPassword;
    @Resource
    DoctorMapper doctorMapper;

    private final IOAuthService oAuthService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FebsResponse saveWxUser(WxUserDTO wxUserDTO) {
        FebsResponse febsResponse = new FebsResponse();
        if (!"wx_mobile".equals(wxUserDTO.getType())) {
            log.info("微信登录参数解析失败：type");
            febsResponse.code(ResponseCode.WRONG.getCode());
            febsResponse.message("微信登录参数解析失败：type");
            return febsResponse;
        }
        String encryptedData = wxUserDTO.getEncryptedData();
        String iv = wxUserDTO.getIv();
        String sessionKey = wxUserDTO.getSessionKey();
        if(StringUtils.isBlank(sessionKey)){
            log.info("服务器开小差了再试一下");
            febsResponse.code(ResponseCode.WRONG.getCode());
            febsResponse.message("服务器开小差了再试一下");
            return febsResponse;
        }
        log.info("登录参数session_key【{}】",sessionKey);
        String result = WXCore.decrypt(appid, encryptedData, sessionKey, iv);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if(jsonObject == null) {
            log.info("微信登录参数解析失败");
            febsResponse.code(ResponseCode.WRONG.getCode());
            febsResponse.message("微信登录参数解析失败");
            return febsResponse;
        }
        String phone = jsonObject.getString("phoneNumber");
        String username = "wx" + phone;
        WxUser wxUser = new WxUser();
        LambdaQueryWrapper<WxUser> queryWrapperUser = new LambdaQueryWrapper<>();
        queryWrapperUser.eq(WxUser::getMobile, phone);
        List<WxUser> wxUserList = this.wxUserMapper.selectList(queryWrapperUser);
        String id = "";
        if(wxUserList.size() == 0) {
            id = UUID.randomUUID().toString();
            wxUser.setMobile(phone);
            wxUser.setId(id);
            wxUser.setUserName(username);
            boolean isAdd = this.save(wxUser);
            if(!isAdd){
                log.info("微信用户注册失败");
                febsResponse.code(ResponseCode.WRONG.getCode());
                febsResponse.message("微信用户注册失败");
                return febsResponse;
            }
        }
        else{
            wxUser = wxUserList.get(0);
            id = wxUser.getId();
        }
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Doctor::getWxUserId, id);
        List<Doctor> doctorList = doctorMapper.selectList(queryWrapper);
        HashMap dataMap = new HashMap();
        dataMap.put("wxUser", wxUser);
        if(doctorList.size() > 0){
            dataMap.put("doctorList", doctorList);
        }

        // 获取OAuth令牌
        OAuthToken oAuthToken = oAuthService.getOAuthInfo(username);
        if(null == oAuthToken) {
            boolean canAdd = oAuthService.checkUsername(username);
            if (canAdd) {
                UserDTO userDTO = new UserDTO();
                userDTO.setUsername(username);
                userDTO.setPassword(userRegisterPassword);
                userDTO.setSex("0");
                userDTO.setMobile(phone);
                userDTO.setStatus("1");
                userDTO.setRoleId("1");
                String add = oAuthService.addSysUser(userDTO);
            }
            oAuthToken = oAuthService.getOAuthInfo(phone);
        }
        dataMap.put("oAuthToken", oAuthToken);
        febsResponse.code(ResponseCode.SUCCESS.getCode());
        febsResponse.data(dataMap);
        return febsResponse;
    }

    private final WxUserMapper wxUserMapper;

    @Override
    public IPage<WxUser> findWxUsers(QueryRequest request, WxUser wxUser) {
        LambdaQueryWrapper<WxUser> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        Page<WxUser> page = new Page<>(request.getPageNum(), request.getPageSize());
        return this.page(page, queryWrapper);
    }

    @Override
    public List<WxUser> findWxUsers(WxUser wxUser) {
        LambdaQueryWrapper<WxUser> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createWxUser(WxUser wxUser) {
        wxUser.setId(UUID.randomUUID().toString());
        this.save(wxUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWxUser(WxUser wxUser) {
        this.saveOrUpdate(wxUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteWxUser(WxUser wxUser) {
        LambdaQueryWrapper<WxUser> wapper = new LambdaQueryWrapper<>();
        // TODO 设置删除条件
        this.remove(wapper);
    }
}
